package com.ruoyi.common.utils.file;

import com.ruoyi.framework.config.MinioConfig;
import io.minio.*;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
public class MinioUtil {
    private final MinioConfig config;
    private final MinioClient minioClient;

    /**
     * 创建桶
     * @param name 桶的名称*/
    public boolean createBucket(String name){
        if(StringUtils.hasLength(name)){
            try {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }
    /**
     * 验证桶是否存在*/
    public boolean exstsBucket(String name){
        if(StringUtils.hasLength(name)){
            try {
                minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
                return true;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 上传单个对象
     * @param file 上传的文件对象*/
    public String uploadFile(MultipartFile file){
//        return uploadFile(config.getBucket(),rename(file.getOriginalFilename()),file.getInputStream(),file.getSize(),file.getContentType());
        try{
            return uploadFile(rename(file.getOriginalFilename()),file.getBytes(),file.getContentType());
        }catch (Exception e){
            return null;
        }
    }
    /**
     * 上传单个文件
     * @param data 文件内容
     * @param objName 对象名称
     * @param type 对象的类型*/
    public String uploadFile(String objName,byte[] data,String type){
        return uploadFile(config.getBucket(),objName,new ByteArrayInputStream(data),data.length,type);
    }
    /**
     * 上传单个文件
     * @param bucket 桶的名称
     * @param objName 对象名
     * @param data 对象内容
     * @param size 对象大小
     * @param type 对象类型*/
    public String uploadFile(String bucket, String objName, InputStream data, long size, String type){
        if(StringUtils.hasLength(bucket)){
            try {
                minioClient.putObject(PutObjectArgs.builder().
                        bucket(bucket).
                        object(objName).
                        contentType(type).
                        stream(data,size,-1)
                        .build());
                return config.getUrl()+"/"+bucket+"/"+objName;
            } catch (Exception e) {

            }
        }
        return null;
    }
    /**
     *上传的文件名 重命名并限制长度 */
    public String rename(String name){
        if(name.length()>50){
            name=name.substring(name.length()-50);
        }
        return System.currentTimeMillis()+name;
    }

    /**
     * 验证对象是否存在 对象名*/
    public boolean existsObject(String bucket,String objName){
        try {
            GetObjectResponse response=minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objName).build());
            return response!=null && StringUtils.hasLength(response.object());
        }  catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 上传多个对象
     * @param files 上传的文件数组*/
    public Map<String,String> uploadFiles(MultipartFile[] files){
        Map<String,String> map=new HashMap<>();
        for (MultipartFile file: files) {
            String objName=rename(file.getOriginalFilename());
            String url=uploadFile(file);
            if(url!=null){
                map.put(objName,url);
            }else {
                map.put(file.getOriginalFilename(),"本文件上传失败");
            }
        }
        return map;
    }
    /**
     * 删除对象*/
    public boolean delObject(String bucket,String objName){
        try{
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objName).build());
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除多个对象*/
    public Map<String,String> delObject(String bucket, List<String> objs){
        Map<String,String> map=new HashMap<>();
        for (String o:objs) {
            map.put(o,"删除："+delObject(bucket,o));
        }
        return map;
    }
    /**
     * 创建临时访问地址
     * @param bucket 桶
     * @param objName 对象名
     * @param seconds 访问地址的有效期*/
    public String createUrlTime(String bucket,String objName,int seconds){
        try{
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(bucket)
                    .object(objName).expiry(seconds, TimeUnit.SECONDS)
                    .build());
        }catch (Exception e){
            return null;
        }

    }
    /**
     * 下载文件*/
    public byte[] downloadObj(String bucket,String objName) {
        try {
           InputStream data=minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(objName).build());
           if(data!=null){
              return IOUtils.toByteArray(data);
           }
        } catch (Exception e) {
           e.printStackTrace();
        }
        return null;
    }
    /**
     * 大文件上传-分片上传+断点续传*/

}
